package org.zoomdev.zoom.aop.factory;

import org.zoomdev.zoom.aop.FilteredInterceptorFactory;
import org.zoomdev.zoom.aop.Interceptor;
import org.zoomdev.zoom.common.utils.TypeReference;
import org.zoomdev.zoom.ioc.IocException;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;

public abstract class AnnotationInterceptorFactory<T extends Annotation> extends TypeReference<T>
        implements FilteredInterceptorFactory {


    Class<T> annotationClass;

    public AnnotationInterceptorFactory() {
        super();
        annotationClass = getType();
    }


    @Override
    public boolean accept(Class<?> targetClass, Method method) {
        return targetClass.isAnnotationPresent(annotationClass) || method.isAnnotationPresent(annotationClass);
    }

    @Override
    public void createInterceptors(Class<?> targetClass, Method method, List<Interceptor> interceptors) {
        T annotation = method.getAnnotation(annotationClass);
        if (annotation == null) {
            annotation = targetClass.getAnnotation(annotationClass);
        }
        if (annotation != null) {
            createInterceptors(annotation, targetClass, method, interceptors);
        }
    }


    public void createInterceptors(T annotation, Class<?> targetClass, Method method, List<Interceptor> interceptors) {
        int modifiers = method.getModifiers();
        if (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers)) {
            throw new IocException("暂不支持private和final方法的aop:" + method + " 若要使用aop，请改成protected");
        }
        createInterceptor(annotation, targetClass, method, interceptors);
    }

    protected abstract void createInterceptor(T annotation, Class<?> targetClass, Method method, List<Interceptor> interceptors);


}
